# -*- coding: utf-8 -*-
# @author: HRUN
from lib2to3.pgen2.parse import ParseError

from rest_framework import serializers
from common.encryption_and_decryption import encrypt_field,load_key
from performance.models import server, presetting, PerformanceTask, TaskScence, TaskStep, TaskScenceStep


class ServerSerializer(serializers.ModelSerializer):
    class Meta:
        model = server
        fields = '__all__'

    def encrypt(self, value):
        # 加密字段
        key = load_key()
        return encrypt_field(value,key)


    def create(self, validated_data):
        # 在保存之前加密密码
        encrypted_passwd = self.encrypt(validated_data.get('sys_user_passwd'))
        validated_data['sys_user_passwd'] = encrypted_passwd
        return super().create(validated_data)

    def update(self, instance, validated_data):
        """
        更新数据时，对密码进行加密
        """
        passwd = validated_data.get('sys_user_passwd')
        if passwd and not self.is_encrypted(passwd):
            # 如果密码是明文的，则进行加密
            encrypted_passwd = self.encrypt(passwd)
            validated_data['sys_user_passwd'] = encrypted_passwd

        return super().update(instance, validated_data)

    def is_encrypted(self, passwd):

        return len(passwd) >= 64
    def validate(self, data):
        is_update = self.instance is not None

        if data.get('default_code'):
            if is_update:
                if server.objects.filter(default_code=True).exclude(id=self.instance.id).exists():
                    raise serializers.ValidationError('只能设置一个默认服务器')
            else:
                if server.objects.filter(default_code=True).exists():
                    raise serializers.ValidationError('只能设置一个默认服务器')

        return data


class PresettingSerializer(serializers.ModelSerializer):
    serverNames = serializers.SerializerMethodField()
    def get_serverNames(self, obj):
        if obj.serverArray.all().count() == 0:
            return []
        return [server.name for server in obj.serverArray.all()]
    def validate(self, data):
        if not data.get('serverArray') :
            raise serializers.ValidationError('机器不能为空,请检查是否有设置默认机器或选择机器！')

        return data

    class Meta:
        model = presetting
        fields = '__all__'


class PerformanceTaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = PerformanceTask
        fields = '__all__'



class TaskScenceSerializer(serializers.ModelSerializer):
    env_name = serializers.StringRelatedField(source='env')
    class Meta:
        model = TaskScence
        fields = '__all__'


class ScenceStepSerializer(serializers.ModelSerializer):
    class Meta:
        model = TaskStep
        fields = '__all__'


class TaskScenceStepSerializer(serializers.ModelSerializer):
    children = serializers.SerializerMethodField()
    stepInfo = serializers.SerializerMethodField(method_name='get_step_info')

    def get_step_info(self, obj):
        if obj.step:
            return ScenceStepSerializer(obj.step, context=self.context).data
        return None

    def get_children(self, obj):
        children_data = []
        if obj.children:
            # 修改查询集以确保子节点按照 sort 字段排序
            children_query = obj.children.order_by('sort')
            # 使用相同的序列化器对子节点进行序列化
            serializer = self.__class__(children_query, many=True, context=self.context)
            children_data = serializer.data
        return children_data

    class Meta:
        model = TaskScenceStep
        fields = '__all__'


# --------------------------性能运行过程序列化------------------------------


class ControllerSerializer(serializers.ModelSerializer):
    title = serializers.CharField(source='name')
    class Meta:
        model = TaskStep
        fields = ['id', 'title', 'content', 'type', 'script', 'status', 'weight']


class PerformanceStepDataSerializer(serializers.ModelSerializer):
    """用例步骤与接口嵌套的序列化器"""

    children = serializers.SerializerMethodField()
    stepInfo = serializers.SerializerMethodField(method_name='get_step_info')

    def get_step_info(self, obj):
        if obj.step:
            return ControllerSerializer(obj.step, context=self.context).data
        return None
    def get_children(self, obj):
        children_data = []
        if obj.children:
            # 修改查询集以确保子节点按照 sort 字段排序
            children_query = obj.children.order_by('sort')
            # 使用相同的序列化器对子节点进行序列化
            serializer = self.__class__(children_query, many=True, context=self.context)
            children_data = serializer.data
        return children_data

    class Meta:
        model = TaskScenceStep
        fields = '__all__'


class PerformanceScenceDataSerializer(serializers.ModelSerializer):
    """测试用例嵌套用例步骤运行序列化器"""
    taskscencestep_set = PerformanceStepDataSerializer(many=True)

    def filter_steps_status(self,step_data):
        # 如果当前节点的status为False，则直接过滤掉当前节点及其所有子节点
        if not step_data['status']:
            return False

        # 如果有子节点，则递归检查子节点
        if step_data.get('children'):
            filtered_children = []
            # 遍历子节点
            for child_step in step_data['children']:
                # 递归检查子节点
                if self.filter_steps_status(child_step):
                    # 如果子节点的status为True，则将其加入过滤后的子节点列表
                    filtered_children.append(child_step)

            # 更新当前节点的子节点列表为过滤后的子节点列表
            step_data['children'] = filtered_children

        # 返回当前节点是否保留的状态
        return step_data['status'] or bool(step_data.get('children'))

    def to_representation(self, instance):
        # 调用父类的 to_representation 方法获取 TestCase 的序列化数据
        representation = super().to_representation(instance)

        # 获取用例步骤数据
        steps_data = representation['taskscencestep_set']

        # 过滤掉 status 为 False 的数据及其子节点
        filtered_steps_data = [step_data for step_data in steps_data if
                               self.filter_steps_status(step_data.get('stepInfo')) and not step_data.get('parent')]

        if not filtered_steps_data:
            raise ParseError("没有启用的用例步骤数据")

        representation['taskscencestep_set'] = filtered_steps_data
        return representation

    class Meta:
        model = TaskScence
        fields = ['id', 'name', 'env', 'weight', 'taskscencestep_set']



class PerformanceTaskRunSerializer(serializers.ModelSerializer):
    taskScence = PerformanceScenceDataSerializer(many=True)
    presetting = PresettingSerializer()

    class Meta:
        model = PerformanceTask
        fields = ['id', 'project','taskName','taskScence', 'presetting']